import * as THREE from "three";
// 引入d3.js
import * as d3 from "d3";
// 片元着色器代码
import outputFragment from "./output_fragment.glsl.js";
// 省份名称对象
import { provinceNameObj } from "../provinceName/index.js";

const waterObj = {};
const mapModel = new THREE.Group();
mapModel.rotateX(-Math.PI / 2);
mapModel.name = "国";
// 墨卡托投影转换
const projection = d3.geoMercator().center([107.067641, 36.226277]).translate([0, 0]);
// 省会城市数据
const cityData = [];
// 地图模型侧边材质
const sideMaterial = new THREE.MeshBasicMaterial({
  // color: '#00BFFF',
  color: "#1EB4E6",
  transparent: true,
  opacity: 1,
});
// 侧边材质uniform
let mapUf = {
  uTime: { value: 0.0 },
  uHeight: { value: 10 },
  uColor: { value: new THREE.Color("#1EB4E6") },
  uStart: { value: -10 },
  uSpeed: { value: 6 },
};
sideMaterial.onBeforeCompile = (shader) => {
  shader.uniforms = {
    ...shader.uniforms,
    ...mapUf,
  };
  shader.vertexShader = shader.vertexShader.replace(
    "void main() {",
    `
              varying vec3 vPosition;
              void main() {
                vPosition = position;
            `
  );
  shader.fragmentShader = shader.fragmentShader.replace(
    "void main() {",
    `
              varying vec3 vPosition;
              uniform float uTime;
              uniform vec3 uColor;
              uniform float uSpeed;
              uniform float uStart;
              uniform float uHeight;
              void main() {
            `
  );
  shader.fragmentShader = shader.fragmentShader.replace("#include <output_fragment>", outputFragment);
};
const quanGuoTexture = new THREE.TextureLoader().load("./quanGuo.png");
quanGuoTexture.flipY = false;
quanGuoTexture.wrapS = THREE.RepeatWrapping;
quanGuoTexture.wrapT = THREE.RepeatWrapping;
quanGuoTexture.repeat.set(0.00608, 0.00825);
quanGuoTexture.offset.set(0.5448, 0.549);
// 加载全国地图数据
async function loadChinaMapData() {
  // 文件加载器，设置类型为json
  const fileLoader = new THREE.FileLoader();
  fileLoader.responseType = "json";
  // 加载全国降水量数据
  const waterData = await fileLoader.loadAsync("./water.json");
  waterData.arr.forEach((obj) => {
    waterObj[obj["name"]] = obj["value"];
  });
  // 加载全国地图数据
  //   const mapData = await fileLoader.loadAsync("./map.json");
  const mapData = await fileLoader.loadAsync("./newMap.json");
  //   const mapData = await fileLoader.loadAsync("http://211.143.122.110:18062/mapdata/geojson/areas_v3_full/all/100000.json");
  operationData(mapData, waterObj);
}
// 解析地图json数据
function operationData(data, waterObj) {
  // 全国信息
  const features = data.features;
  features.forEach((feature, index) => {
    // 单个省份
    const province = new THREE.Object3D();
    // 设置省份名称后续用于查找
    province.name = feature.properties.name;
    province.animationActive = false; // 新增属性来跟踪动画状态
    province.animationTimer = null; // 用于存储定时器的引用
    // 保存各省adcode后续用于接口请求地级市数据
    province.userData.adcode = feature.properties.adcode;
    // 省份边线
    const provinceLine = new THREE.Object3D();
    provinceLine.name = "省份边线";
    provinceLine.position.z += 0.2;
    province.add(provinceLine);
    // 省份坐标数据
    const coordinates = feature.geometry.coordinates;
    // 颜色，color2表示降水量相对较高的，color1表示降水量相对较底的
    const color1 = new THREE.Color("#1BDAFC");
    const color2 = new THREE.Color("#F3FD27");
    const color3 = new THREE.Color("#FD8B24");
    // 降水量标准值，用于颜色插值
    const standard1 = 50000; // 低至中等降水量的界限
    const standard2 = 80000; // 中等至高降水量的界限
    const value = waterObj[province.name];
    let lerpColor;
    if (value < standard1) {
      lerpColor = color1.clone().lerp(color2, value / standard1);
    } else {
      lerpColor = color2.clone().lerp(color3, value / standard2);
    }
    // 创建省份边界线和模型-多个多边形
    if (feature.geometry.type === "MultiPolygon") {
      coordinates.forEach((coordinate) => {
        coordinate.forEach((rows) => {
          // 省模型
          const mesh = drawExtrudeMesh(rows, lerpColor);
          mesh.rotateX(Math.PI);
          province.add(mesh);
          // 边线
          const line = lineDraw(rows);
          provinceLine.add(line);
        });
      });
    }
    // 创建省份边界线和模型-单个多边形
    if (feature.geometry.type === "Polygon") {
      coordinates.forEach((coordinate) => {
        // 省模型
        const mesh = drawExtrudeMesh(coordinate, lerpColor);
        mesh.rotateX(Math.PI);
        province.add(mesh);
        // 边线
        const line = lineDraw(coordinate);
        provinceLine.add(line);
      });
    }
    provinceLine.userData.cityData = feature.geometry;
    mapModel.add(province);
    const provinceName = provinceNameObj[feature.properties.name];
    if (provinceName) {
      const x = provinceName.position.x;
      const y = provinceName.position.y;
      // 存入省会位置，后续
      provinceLine.userData.center = [x, y];
      cityData.push({
        name: province.name,
        x: x,
        y: y,
      });
      provinceLine.add(provinceNameObj[feature.properties.name]);
    }
  });
}

// 绘制模型
function drawExtrudeMesh(polygon, color) {
  // 创建形状
  const shape = new THREE.Shape();
  // 遍历坐标数组，绘制形状
  polygon.forEach((row, i) => {
    // 坐标点转换
    const [x, y] = projection(row);
    if (i === 0) {
      shape.moveTo(x, y);
    }
    shape.lineTo(x, y);
  });
  // 将形状进行拉伸
  const geometry = new THREE.ExtrudeGeometry(shape, {
    depth: 10,
    bevelEnabled: true,
    bevelSegments: 10,
    bevelThickness: 0.1,
  });
  // 模型顶部材质
  const material = new THREE.MeshStandardMaterial({
    // 默认先使用深蓝色，不适用计算插值的color
    color: new THREE.Color("#00FFFF"),
    map: quanGuoTexture,
    emissiveIntensity: 0.1,
    transparent: true,
    opacity: 1,
  });
  const mesh = new THREE.Mesh(geometry, [material, sideMaterial]);
  // 存储这个颜色，作为后面旅游量按钮点击的颜色
  mesh.color = color;
  // 存储这个纹理
  mesh.texture = quanGuoTexture;
  return mesh;
}

// 绘制边界线
function lineDraw(polygon) {
  const lineGeometry = new THREE.BufferGeometry();
  const pointsArray = new Array();
  polygon.forEach((row) => {
    const [x, y] = projection(row);
    // 创建三维点
    pointsArray.push(new THREE.Vector3(x, -y, 0));
  });
  // 放入多个点
  lineGeometry.setFromPoints(pointsArray);
  const lineMaterial = new THREE.MeshBasicMaterial({
    // color: '#00C5CD'
    color: "#00ffff",
    // color: '#87CEFF'
  });
  return new THREE.Line(lineGeometry, lineMaterial);
}
export { loadChinaMapData, mapModel, cityData, mapUf, projection, waterObj };
